package com.sean.item;

import java.lang.reflect.Array;
import java.lang.reflect.Field;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

/**
 * 使用该控件可以使画布旋转180度
 * @author Sean
 *
 */
public class RotateLayout extends RelativeLayout {
	
	public static final String TAG = "RotateLayout";
	
	private boolean mIsRotate = false;
	
	
	private static int SAMPLE_X;
	private static int SAMPLE_Y;
	private static int NUM_SAMPLE_DATA;
	private static Class mMotionEventClass;
	
	static {
		try {
			mMotionEventClass = Class.forName("android.view.MotionEvent");
			Field field = mMotionEventClass.getDeclaredField("SAMPLE_X");
			field.setAccessible(true);
			SAMPLE_X = field.getInt(MotionEvent.class);
			
			field = mMotionEventClass.getDeclaredField("SAMPLE_Y");
			field.setAccessible(true);
			SAMPLE_Y = field.getInt(MotionEvent.class);
			
			field = mMotionEventClass.getDeclaredField("NUM_SAMPLE_DATA");
			field.setAccessible(true);
			NUM_SAMPLE_DATA = field.getInt(MotionEvent.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public RotateLayout(Context context) {
		super(context);
	}
	
	public RotateLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	/**
	 * 是否旋转180度
	 * @param isRotate
	 */
	public void setRotate(boolean isRotate) {
		this.mIsRotate = isRotate;
		invalidate();
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		View view = this.getChildAt(0);
		if(view != null) {
			view.layout(l, t, r, b);
		}
	}
	
	@Override
	protected void dispatchDraw(Canvas canvas) {
		if(mIsRotate) {
			canvas.rotate(180);
			canvas.translate(-this.getMeasuredWidth(), -this.getMeasuredHeight());
			super.dispatchDraw(canvas);
			this.invalidate();
		} else {
			super.dispatchDraw(canvas);
		}
	}
	
//	@Override
//	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//		this.setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), 
//				MeasureSpec.getSize(heightMeasureSpec));
//		if(this.getChildAt(0) != null)
//			getChildAt(0).measure(widthMeasureSpec, heightMeasureSpec);
//	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		if(mIsRotate) {
			try {
				Field field = mMotionEventClass.getDeclaredField("mNumPointers");
				field.setAccessible(true);
				int numPointers = field.getInt(event);
				
				field = mMotionEventClass.getDeclaredField("mNumSamples");
				field.setAccessible(true);
				int numSamples = field.getInt(event);
				
				
				field = mMotionEventClass.getDeclaredField("mDataSamples");
				field.setAccessible(true);
				Object dataSimples = field.get(event);
				
				final int N = numPointers * numSamples * NUM_SAMPLE_DATA;
				int width = this.getMeasuredWidth();
				int height = this.getMeasuredHeight();
		        for (int i = 0; i < N; i+= NUM_SAMPLE_DATA) {
		        	Array.set(dataSimples, i + SAMPLE_X, new Float(width - (Float)Array.get(dataSimples, i + SAMPLE_X)));
		        	Array.set(dataSimples, i + SAMPLE_Y, new Float(height - (Float)Array.get(dataSimples, i + SAMPLE_Y)));
		        }
				field.set(event, dataSimples);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
//		printSamples(event);
//		Log.d(TAG, "location >> x : " + event.getX() + "; y : " + event.getY());
//		Log.i(TAG, "SAMPLE_X:" + SAMPLE_X + "; SAMPLE_Y" + SAMPLE_Y + "; NUM_SAMPLE_DATA:" + NUM_SAMPLE_DATA);
		return super.dispatchTouchEvent(event);
	}
	
	void printSamples(MotionEvent ev) {
	     final int historySize = ev.getHistorySize();
	     final int pointerCount = ev.getPointerCount();
	     Log.d(TAG, "historySize:" + historySize + "; pointerCount:" + pointerCount);
	     for (int h = 0; h < historySize; h++) {
	         for (int p = 0; p < pointerCount; p++) {
	             Log.d(TAG, "  pointer " + ev.getPointerId(p) + ": (" 
	            		 + ev.getHistoricalX(p, h) + "," + ev.getHistoricalY(p, h) + ")");
	         }
	     }
	     
	     Log.d(TAG, "----------------------------------------------------");
	     System.out.printf("At time %d:", ev.getEventTime());
	     for (int p = 0; p < pointerCount; p++) {
	    	 Log.d(TAG, "  pointer " + ev.getPointerId(p) + ": (" 
            		 + ev.getX(p) + "," + ev.getY(p) + ")");
	     }
	 }

}
